using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using UCL.Powersource;
using UCL.Powersource.Analysis;
using UCL.Powersource.ViewModels.Analysis;

namespace PowersourceUIToolkit
{

    

    public abstract class Bootstrapper : InitializedLifeCycleBase
    {

        public 
            Bootstrapper()
        {
            ExtensibilityFiles = new List<string>();
        }

       //protected string ExtensibilityDirectory;
        protected List<string> ExtensibilityFiles;

        protected abstract void Configure();
        protected abstract void BuildUp(object instance);
        internal protected abstract IEnumerable<Assembly> SelectAssemblies();
        internal protected abstract bool ValidateAssembly(string assemblyFilename);
        protected abstract void InitializeIoCDependants();
        protected abstract Type GetDefaultInterfaceImplementationType(Type interfaceType);
        protected abstract IEnumerable<Type> GetDefaultInterfaceImplementationTypes();

        //protected ResourceDictionary DefaultResourceDictionary;

        /// <summary>
        /// Override this to provide an IoC specific implementation.
        /// </summary>
        /// <param name="service">The service to locate.</param>
        /// <param name="key">The key to locate.</param>
        /// <returns>The located service.</returns>
        protected virtual object GetInstance(Type service, string key)
        {
            return Activator.CreateInstance(service);
        }


        
        

        /// <summary>
        /// Override this to provide an IoC specific implementation
        /// </summary>
        /// <param name="service">The service to locate.</param>
        /// <returns>The located services.</returns>
        protected virtual IEnumerable<object> GetAllInstances(Type service)
        {
            return new[] { Activator.CreateInstance(service) };
        }


        protected override bool OnInitializing()
        {
            if (Log == null) Log = LogManager.GetLog(this.GetType());
            Log.Debug("Initializing Bootstrapper.");
            Log.Debug("Initializing AssemblySource - AssemblySource.Instance.AddRange(SelectAssemblies());.");
            AssemblySource.AddFromList(ExtensibilityFiles, this);
            AssemblySource.AddFromBootStrapper(this);

            Log.Debug("Summary of AssemblySource");
            foreach (var it in AssemblySource.Instance)
            {
                Log.Debug("Loaded assembly : {0} - {1}; Token={2}", it.FullName,it.GetName(),it.GetName().GetPublicKeyToken());
            }

            foreach (var it in AssemblySource.IgnoredAssemblyFileNames)
            {
                Log.Debug("Ignored assembly : {0} - {1}", it.AssemblyFileName,it.Reason);
            }

            Log.Debug("Bootstrappper calls delegate configure.");
            Configure();
            Log.Debug("Setting IOC calls.");
            IoC.GetInstance = GetInstance;
            IoC.GetAllInstances = GetAllInstances;
            IoC.BuildUp = BuildUp;
            //IoC.GetResourceDictionary = () => DefaultResourceDictionary;
            IoC.GetDefaultInterfaceImplementationType = GetDefaultInterfaceImplementationType;
            IoC.GetDefaultInterfaceImplementationTypes = GetDefaultInterfaceImplementationTypes;
            Log.Debug("Setting IOC calls done. ");
            InitializeIoCDependants();
            return true;
        }

        
        

        protected override void OnDisposing()
        {
            IoC.Default.Clear();
            AssemblySource.Clear();
            Trace.WriteLine("Bootstrapper disposed. IoC cleaned. Supressing finalize.");
        }
    }
}
